<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    /*
    * 工厂方法模式去掉了简单工厂模式中工厂方法的静态属性，使得它可以被子类继承。这样在简单工厂模式里，
    * 集中在工厂方法上的压力尅由工厂方法模式里不停的工厂子类来分担。
    *
    * 1.抽象工厂角色：工厂方法模式的核心。是具体工厂角色必须实现的接口或者必须继承的父类
    * 2.具体工厂角色：含有和具体业务逻辑有关的代码。创建对应的具体产品的对象。
    * 3.抽象产品角色：是具体产品继承的父类或者实现的接口。
    * 4.具体产品角色：具体工厂角色所创建的对象就是此角色的实例。
    *
    * 解决工厂不能被继承的问题，要符合开闭原则。
    * 工厂方法模式优缺点：
    *   优点：符合开闭原则，增加一个产品，只需要添加一个具体的产品类和具体的工厂类，使用者无需关心产品如何去创造
    *   缺点：系统代码比较复杂
    * */

    //抽象的产品电脑 规则
    class Computer{
        //功能
        code(){
            console.log("某某电脑能写代码")
        }
    }

    //具体产品
    class Xiaomi extends  Computer{
        code() {
            console.log("小米电脑能写代码")
        }
    }

    class Dell extends Computer{
        code() {
            console.log("戴尔电脑能写代码")
        }
    }

    //抽象工厂
    class ComputerFactory{
        createComputer(){
            console.log("某某工厂生产某某电脑")
        }
    }

    //具体工厂
    class XiaomiFactory extends ComputerFactory{
        createComputer() {
            console.log("小米工厂生产小米电脑")
            return new Xiaomi()
        }
    }

    class DellFactory extends ComputerFactory{
        createComputer() {
            console.log("戴尔工厂生产戴尔电脑")
            return new Dell()
        }
    }

    let xiaomi = new XiaomiFactory() //实例对象小米
    xiaomi.createComputer().code() //实例对象调用方法

    let dell = new DellFactory() //实例对象戴尔
    dell.createComputer().code() //实例对象调用方法
</script>
</body>
</html>